﻿#pragma once

#include "../MirControls/MirControl.h"
#include "../MirControls/MirLabel.h"
#include "../KeyBindSettings.h"
#include "../../Shared/Enums.h"
#include <string>
#include <vector>
#include <stdexcept>
#include <any>
#include <cstdint>
#include "exceptionhelper.h"
#include "../../stringhelper.h"
#include "../../tangible_filesystem.h"

//C# TO C++ CONVERTER NOTE: Forward class declarations:
namespace Client { class PeekMsg; }

using namespace Client::MirControls;
using namespace Client::MirGraphics;
using namespace Client::MirNetwork;
using namespace Client::MirScenes;
using namespace Client::MirSounds;
using namespace SlimDX::Direct3D9;
using namespace SlimDX::Windows;
//C# TO C++ CONVERTER TODO TASK: C# to C++ Converter could not confirm whether this is a namespace alias or a type alias:
//using Font = System::Drawing::Font;

namespace Client
{
    class CMain : public RenderForm
    {
    public:
        static MirControl *DebugBaseLabel;
        static MirControl *HintBaseLabel;
        static MirLabel *DebugTextLabel;
        static MirLabel *HintTextLabel;
        static MirLabel *ScreenshotTextLabel;
        static Graphics *Graphics;
        static Point *MPoint;

        static Stopwatch *const Timer;
        const static DateTime StartTime;
        static long long Time;
        static long long OldTime;
        virtual ~CMain()
        {
            delete components;
        }

        static DateTime getNow();
        static Random *const Random;

        static std::string DebugText;

    private:
        static long long _fpsTime;
        static int _fps;
    public:
        static int FPS;

        static long long PingTime;
        static long long NextPing;

        static bool Shift;
        static bool Alt;
        static bool Ctrl;
        static bool Tilde;
        static double BytesSent;
        static double BytesReceived;

        static KeyBindSettings *InputKeys;

        CMain();

    private:
        void CMain_Load(std::any sender, EventArgs *e);


        static void Application_Idle(std::any sender, EventArgs *e);

        static void CMain_Deactivate(std::any sender, EventArgs *e);

    public:
        static void CMain_KeyDown(std::any sender, KeyEventArgs *e);
        static void CMain_MouseMove(std::any sender, MouseEventArgs *e);
        static void CMain_KeyUp(std::any sender, KeyEventArgs *e);
        static void CMain_KeyPress(std::any sender, KeyPressEventArgs *e);
        static void CMain_MouseDoubleClick(std::any sender, MouseEventArgs *e);
        static void CMain_MouseUp(std::any sender, MouseEventArgs *e);
        static void CMain_MouseDown(std::any sender, MouseEventArgs *e);
        static void CMain_MouseClick(std::any sender, MouseEventArgs *e);
        static void CMain_MouseWheel(std::any sender, MouseEventArgs *e);

    private:
        static void UpdateTime();
        static void UpdateEnviroment();

        static void RenderEnvironment();

        static void CreateDebugLabel();

        static void CreateHintLabel();

        static void ToggleFullScreen();

    public:
        void CreateScreenShot();

        static void SaveError(const std::string &ex);

        static void SetResolution(int width, int height);


        #pragma region ScreenCapture

        //private Bitmap CaptureScreen()
        //{

        //}

        #pragma endregion

        #pragma region Idle Check
    private:
        static bool getAppStillIdle();

//C# TO C++ CONVERTER NOTE: The following .NET DllImport attribute was converted using the Microsoft-specific __declspec(dllimport):
//[SuppressUnmanagedCodeSecurity][DllImport("User32.dll", CharSet = CharSet::Auto)]
        __declspec(dllimport) static bool PeekMessage(PeekMsg &msg, std::intptr_t hWnd, unsigned int messageFilterMin, unsigned int messageFilterMax, unsigned int flags);

    private:
//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: [StructLayout(LayoutKind.Sequential)] private struct PeekMsg
        class PeekMsg
        {
        private:
            const std::intptr_t hWnd;
            Message *const msg;
            const std::intptr_t wParam;
            const std::intptr_t lParam;
            const unsigned int time;
            Point *const p;
        public:
            virtual ~PeekMsg()
            {
                delete msg;
                delete p;
            }

        };
        #pragma endregion

    private:
        void CMain_FormClosing(std::any sender, FormClosingEventArgs *e);

    protected:
        void WndProc(Message *&m) override;


    public:
        static std::vector<Cursor*> Cursors;
        static MouseCursor CurrentCursor;
        static void SetMouseCursor(MouseCursor cursor);

    private:
        static void LoadMouseCursors();

    public:
        static Cursor *LoadCustomCursor(const std::string &path);

//C# TO C++ CONVERTER NOTE: The following .NET DllImport attribute was converted using the Microsoft-specific __declspec(dllimport):
//[DllImport("user32.dll", SetLastError = true, CharSet = CharSet::Auto)]
    private:
        __declspec(dllimport) static std::intptr_t LoadCursorFromFile(const std::string &path);


        /// <summary>
        /// Required designer variable.
        /// </summary>
        System::ComponentModel::IContainer *components = nullptr;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected:
        void Dispose(bool disposing) override;

        #pragma region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
    private:
        void InitializeComponent();

        #pragma endregion

    };
}
